{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "from common import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "RESULT_JSON = \"/Users/law/repos/viper/results/ycsb/ycsb_all_revision.json\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "results_raw = json.loads(open(RESULT_JSON).read())\n",
    "assert results_raw[\"context\"][\"library_build_type\"] != \"debug\"\n",
    "BENCHMARKS =  results_raw[\"benchmarks\"]\n",
    "# print(BENCHMARKS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from collections import defaultdict\n",
    "runs = defaultdict(list)\n",
    "\n",
    "FIXTURES = [VIPER, DASH, PMEMKV, HYBRID_FASTER, UTREE, CRL_STORE]\n",
    "BM_TYPES = ['5050_uniform', '1090_uniform', '5050_zipf', '1090_zipf']\n",
    "\n",
    "RUNS = get_benchmarks(BENCHMARKS, FIXTURES, BM_TYPES)\n",
    "\n",
    "# pprint(RUNS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "fig, (lat_axes, tp_axes) = plt.subplots(2, 4, figsize=(20, 5))\n",
    "uniform_5050_ax, uniform_1090_ax, zipf_5050_ax, zipf_1090_ax = lat_axes\n",
    "uniform_5050_ax_tp, uniform_1090_ax_tp, zipf_5050_ax_tp, zipf_1090_ax_tp = tp_axes\n",
    "\n",
    "def get_bm_ax(bm_type):\n",
    "    if bm_type == '5050_uniform': return (uniform_5050_ax, uniform_5050_ax_tp)\n",
    "    if bm_type == '1090_uniform': return (uniform_1090_ax, uniform_1090_ax_tp)\n",
    "    if bm_type == '5050_zipf': return (zipf_5050_ax, zipf_5050_ax_tp)\n",
    "    if bm_type == '1090_zipf': return (zipf_1090_ax, zipf_1090_ax_tp)\n",
    "    raise RuntimeError(f\"Unknown bm_type {bm_type}\")\n",
    "\n",
    "num_threads = sorted({run['threads'] for run in list(RUNS.values())[0]})\n",
    "SEC_IN_US = 1000000\n",
    "\n",
    "for bm_type in BM_TYPES:\n",
    "    (lt_ax, tp_ax) = get_bm_ax(bm_type)\n",
    "#     lt_ax.set_xlabel(\"# Threads\", fontsize=20)\n",
    "#     tp_ax.set_xlabel(\"# Threads\", fontsize=20)\n",
    "    \n",
    "    for (fixture, _) in FIXTURES:        \n",
    "        lat_runs = [r for r in RUNS[(fixture, bm_type)] if f\"{bm_type}_lat\" in r['name']]\n",
    "        tp_runs = [r for r in RUNS[(fixture, bm_type)] if f\"{bm_type}_tp\" in r['name']]\n",
    "        \n",
    "        tp = [run['items_per_second'] / MILLION for run in tp_runs]\n",
    "        hdr_avg = [run['hdr_avg'] / 1000 for run in lat_runs]\n",
    "                \n",
    "        style = STYLES[fixture]\n",
    "        x_vals = [1, 2, 4, 8, 16, 18] if fixture == CRL_STORE[0] and bm_type != 'get' else num_threads\n",
    "        tp_ax.plot(x_vals, tp, marker=style.marker, ms=style.marker_size, \n",
    "                   color=style.color, markeredgewidth=0.5, lw=3)\n",
    "        if fixture == HYBRID_FASTER[0]:\n",
    "            x_vals = []\n",
    "            hdr_avg = []\n",
    "        lt_ax.plot(x_vals, hdr_avg, marker=style.marker, ms=style.marker_size, \n",
    "                   color=style.color, markeredgewidth=0.5, lw=3)\n",
    "        \n",
    "    for ax in [lt_ax, tp_ax]:\n",
    "        ax.set_xticks([1, 4, 8, 16, 24, 32, 36])\n",
    "        ax.set_xlim(0, 37)\n",
    "        ax.grid(axis='y', which='major')\n",
    "        for tick in ax.xaxis.get_major_ticks():\n",
    "            tick.label.set_fontsize(18)\n",
    "        for tick in ax.yaxis.get_major_ticks():\n",
    "            tick.label.set_fontsize(18)\n",
    "\n",
    "#     lt_ax.set_yscale('log')\n",
    "    \n",
    "\n",
    "uniform_5050_ax.set_ylabel(\"Latency\\n(µs/op)\", fontsize=20)\n",
    "uniform_5050_ax.set_title(f\"(a) UNIFORM R50:W50\", fontsize=20)\n",
    "uniform_1090_ax.set_title(f\"(b) UNIFORM R10:W90\", fontsize=20)\n",
    "zipf_5050_ax.set_title(f\"(c) ZIPF R50:W50\",    fontsize=20)\n",
    "zipf_1090_ax.set_title(f\"(d) ZIPF R10:W90\", fontsize=20)\n",
    "\n",
    "uniform_5050_ax.set_ylim(0, 20)\n",
    "uniform_1090_ax.set_ylim(0, 20)\n",
    "zipf_5050_ax.set_ylim(0, 20)\n",
    "zipf_1090_ax.set_ylim(0, 20)\n",
    "\n",
    "uniform_5050_ax_tp.set_ylabel(\"Throughput\\n(Mops/s)\", fontsize=20)\n",
    "uniform_5050_ax_tp.set_title(f\"(e) UNIFORM R50:W50\", fontsize=20)\n",
    "uniform_1090_ax_tp.set_title(f\"(f) UNIFORM R10:W90\", fontsize=20)\n",
    "zipf_5050_ax_tp.set_title(f\"(g) ZIPF R50:W50\",    fontsize=20)\n",
    "zipf_1090_ax_tp.set_title(f\"(h) ZIPF R10:W90\", fontsize=20)\n",
    "\n",
    "uniform_5050_ax_tp.set_ylim(0, 30)\n",
    "uniform_1090_ax_tp.set_ylim(0, 30)\n",
    "zipf_5050_ax_tp.set_ylim(0, 30)\n",
    "zipf_1090_ax_tp.set_ylim(0, 30)\n",
    "\n",
    "fig.text(0.5, -0.05, \"# Threads\", ha='center', fontsize=22)\n",
    "\n",
    "fig.legend(loc='upper center', labels=[f[1] for f in FIXTURES], \n",
    "           bbox_to_anchor=(0.5, 1.1), ncol=6, frameon=False, fontsize=20,\n",
    "           columnspacing=1.3, handletextpad=0.3)\n",
    "\n",
    "for ax in [*tp_axes, *lat_axes]:\n",
    "    hide_border(ax, show_left=True)\n",
    "plt.tight_layout()\n",
    "fig.savefig('charts/ycsb.pdf', bbox_inches='tight')\n",
    "fig.savefig('charts/ycsb.svg', bbox_inches='tight')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
